﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace Senthil.Mobile.WhereAmI
{
    public class LocationAndETAWatcher
    {
        IRouteTracker tracker;
        bool enabled;
        
        bool playedSoundForEvent = false;

        Dictionary<Predicate<LocationGroup>, Action> actionsForLocationGroupChanges = new Dictionary<Predicate<LocationGroup>, Action>();
        Dictionary<Predicate<TimeSpan>, Action> actionsForTimeToDestinationChanges = new Dictionary<Predicate<TimeSpan>, Action>();

        public void Initialize(IRouteTracker tracker)
        {
            this.tracker = tracker;
            actionsForLocationGroupChanges.Clear();
            actionsForTimeToDestinationChanges.Clear();

            Disable();
            Enable();
        }

        public void Disable()
        {
            this.enabled = false;

            if (this.tracker != null)
            {
                this.tracker.LocationChanged -= new EventHandler<LocationChangedEventArgs>(tracker_LocationChanged);
                this.tracker.TimeChanged -= new EventHandler<TimeChangedEventArgs>(tracker_TimeChanged);
            }
        }

        public void Enable()
        {
            this.enabled = true;
            this.tracker.LocationChanged += new EventHandler<LocationChangedEventArgs>(tracker_LocationChanged);
            this.tracker.TimeChanged += new EventHandler<TimeChangedEventArgs>(tracker_TimeChanged);
        }

        public void AddSingleShotActionForLocationChange(Predicate<LocationGroup> predicate, Action action)
        {
            actionsForLocationGroupChanges[predicate] = action;
        }

        public void AddSingleShotActionForETA(Predicate<TimeSpan> predicate, Action action)
        {
            actionsForTimeToDestinationChanges[predicate] = action;
        }

        void tracker_TimeChanged(object sender, TimeChangedEventArgs e)
        {
            TimeSpan t = e.TimeToDestination;
            ExecuteOneShotActions(t, actionsForTimeToDestinationChanges);
        }

        void tracker_LocationChanged(object sender, LocationChangedEventArgs e)
        {
            Location location = e.Location;

            if (location.IsRecognized)
            {
                ExecuteOneShotActions(e.Location.LocationGroup, actionsForLocationGroupChanges);
            }
        }

        private void ExecuteOneShotActions<T>(T t, Dictionary<Predicate<T>, Action> actionsCollection)
        {
            List<Predicate<T>> executedActions = new List<Predicate<T>>();

            foreach (var pair in actionsCollection)
            {
                if (pair.Key(t))
                {
                    pair.Value();
                    executedActions.Add(pair.Key);
                }
            }

            foreach (var element in executedActions)
                actionsCollection.Remove(element);
        }
    }
}
